#include "PlaceButterflyPrimitive.h"

#include "PadStackWidget.h"
#include "Gui.h"
#include "GraphicsButterflyPrimitive.h"

#include "LeIpc7351/PadStackElement.h"
#include "LeIpc7351/Primitives/ButterflyPrimitive.h"

#include "LeGraphicsView/LeGraphicsItem.h"
#include "LeGraphicsView/LeGraphicsItemLayer.h"
#include "LeGraphicsView/LeGraphicsScene.h"
#include "LeGraphicsView/LeGraphicsStyle.h"
#include "LeGraphicsView/LeGraphicsPalette.h"

#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QRectF>

PlaceButterflyPrimitiveTask::PlaceButterflyPrimitiveTask(PadStackWidget *editor)
    : PadStackTask(editor)
    , LeGraphicsSceneEventFilter()
{
    setTile("Butterfly pad");
    setDescription("Place a butterfly pad");
    setIcon(Gui::icon("primitive-special-butterfly"));
    setShortcut(QKeySequence("p,b"));
}

PlaceButterflyPrimitiveTask::~PlaceButterflyPrimitiveTask()
{

}

ButterflyPrimitive::Shape PlaceButterflyPrimitiveTask::shape() const
{
    return m_primitive->shape();
}


void PlaceButterflyPrimitiveTask::start()
{
    m_primitive = new ButterflyPrimitive();
    m_item = new GraphicsButterflyPrimitive(m_primitive);
    m_state = WaitForP1;
    scene()->setEventFilter(this);
    emit started(this);
}

void PlaceButterflyPrimitiveTask::accept()
{
    Q_ASSERT(m_state == Finished);

    scene()->currentLayer()->removeFromLayer(m_item);
    delete m_item;
    m_item = nullptr;
    editor()->currentElement()->setPrimitive(m_primitive); // FIXME
    scene()->setEventFilter(nullptr);
    emit accepted(this);
}

void PlaceButterflyPrimitiveTask::reject()
{
    if (m_state != WaitForP1)
    {
        scene()->currentLayer()->removeFromLayer(m_item);
    }
    delete m_item;
    m_item = nullptr;
    delete m_primitive;
    m_primitive = nullptr;
    scene()->setEventFilter(nullptr);
    emit rejected(this);
}

void PlaceButterflyPrimitiveTask::setShape(ButterflyPrimitive::Shape shape)
{
    if (m_primitive->shape() == shape)
        return;

    m_primitive->setShape(shape);
    emit shapeChanged(m_primitive->shape());
}

void PlaceButterflyPrimitiveTask::drawBackground(QPainter *painter, const QRectF &rect)
{
    Q_UNUSED(painter)
    Q_UNUSED(rect)
}

void PlaceButterflyPrimitiveTask::drawForeground(QPainter *painter, const QRectF &rect)
{
    Q_UNUSED(rect)

    if (m_item == nullptr)
        return;

    painter->setBrush(Qt::NoBrush);
    painter->setPen(QPen(scene()->graphicsPalette().color(LeGraphicsPalette::Highlight), 0));
    painter->drawLine(m_radiusLine);
    painter->setPen(QPen(scene()->graphicsPalette().color(LeGraphicsPalette::Highlight), 0, Qt::DotLine));
    QRectF bRect = m_item->boundingRect();
    bRect.moveCenter(m_item->pos());
    painter->drawRect(bRect);
}

bool PlaceButterflyPrimitiveTask::keyPressEvent(QKeyEvent *event)
{
    Q_UNUSED(event)
    return true;
}

bool PlaceButterflyPrimitiveTask::keyReleaseEvent(QKeyEvent *event)
{
    Q_UNUSED(event)
    return true;
}

bool PlaceButterflyPrimitiveTask::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event)
    return true;
}

bool PlaceButterflyPrimitiveTask::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_state == WaitForP2)
    {
        m_radiusLine.setP2(event->scenePos());
        m_primitive->setSize(qMax(qAbs(m_radiusLine.dx())*2.0,
                                    qAbs(m_radiusLine.dy())*2.0));
    }
    return true;
}

bool PlaceButterflyPrimitiveTask::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_state == WaitForP1)
    {
        m_primitive->setPosition(event->scenePos());
        scene()->currentLayer()->addToLayer(m_item);
        m_radiusLine.setP1(event->scenePos());
        m_state = WaitForP2;
        return true;
    }
    else if (m_state == WaitForP2)
    {
        m_state = Finished;
        accept();
    }
    return true;
}

bool PlaceButterflyPrimitiveTask::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event)
    return true;
}
